Skip to content


ai  101  pytorch  classification  nvidia  cuda  install  tensorrt  yolo  ardupilot  None  ros2  dds  micro ros  xrce  sitl  plugin  SITL  debug  rangefinder  pymavlink  mavros  gazebo  distance sensor  system_time  timesync  cmake  gtest  ctest  cpp  c++  format  fmt  multithreading  spdlog  camera  coordinate system  orb  matching  opencv  build  transformation  computer vision  homography  optical flow  of  trackers  cv  cyclonedds  eprosima  fastdds  simulation  config  ignition  bridge  sdf  tips  ign-transport  sensors  lidar  aptly  apt  encryption  pgp  docker  git  bundle  github  hooks  pre-commit  lxd  container  lxc  x11  profile  vscode  marpit  presentation  marp  markdown  mermaid  video  ffmpeg  gstreamer  cheat-sheet  sdp  v4l2loopback  gi  snippets  cheat Sheet  python  asyncio  future  click  cli  numpy  project  template  black  isort  docs  project document  docstrings  flake8  linter  git-hook  mypy  unittest  pytest  pylint  mock  iterator  generator  logging  tuple  namedtuple  typing  annotation  pyzmq  zmq  msgpack  action  namespace  remap  control2  ros2_control  gdb  qos  tag  plugins  msg  node  zero-copy  shm  tutorial  algorithm  calibration  diff  pid  dev  colcon  colcon_cd  rpi  arm  qemu  settings  behavior  plot  visualization  debugging  diagnostic  diagnostics  tutorials  gst  math  apm  rat_runtime_monitor  web  rosbridge  vue  binding  discovery  gazebo-classic  launch  spawn  cook  gps  imu  ray  gazebo_ros_ray_sensor  ultrsonic  range  ultrasonic  gazebo classic  wrench  effort  odom  ign  gz  xacro  ros_ign  diff_drive  odometry  joint_state  argument  OpaqueFunction  DeclareLaunchArgument  LaunchConfiguration  tmux  nav  slam  test  rclpy  executor  MultiThreadedExecutor  SingleThreadedExecutor  param  dynamic-reconfigure  service  client  setup.py  package.xml  parameter  parameters  custom  msgs  executers  pub  sub  rqt  rviz  rviz2  pose  marker  tf2  deb  package  setup  local_setup  rosdep  package manager  project settings  vcstool  cross-compiler  nano  texture  tmuxp  rootfs  embedded  zah  linux  rm  ubuntu  ip  ss  network  netstat  snap  deploy  ssh  systemd  mkdocs  extensions  socat  networking  serial  udp  tc  mtu  select  px4  robotics  kalman_filter  kalman  filter  control  todo  vscode-ext  json  yaml  schema  yocto  poky  world  gazebo_ros2_control  position_controller  effort_controller  velocity_controller  urdf  gazebo_ros_force  gazebo_ros_joint_state_publisher  robot_state_publisher  joint_state_publisher  projects  vrx  buoyancy 

Table of Content

Logging Formatting#

Formatter enrich the log message by adding more information like: time, python file, logger name and more

simple_formatter.py
import logging

FMT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
logging.basicConfig(format=FMT, level=logging.INFO)

log = logging.getLogger("demo")
log.info("formatter example")
result
2022-11-26 07:10:35,660 - demo - INFO - formatter example
name format desc
asctime %(asctime)s time when the LogRecord was created
name %(name)s Name of the logger used to log the call.
levelname %(levelname)s Text logging level for the message (‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’)
message %(message)s The logged message, computed as msg % args

Custom formatter#

Extend the logging.Formatter class and override the format method

  • Color formatter
  • Custom Level
logging/color.py
import logging

FMT = "%(asctime)s - %(name)s - %(levelname)s -%(message)s"

class CustomFormatter(logging.Formatter):
    GRAY = '\u001b[38;21m'
    BLUE = '\u001b[38;5;39m'
    YELLOW = '\u001b[38;5;226m'
    RED = '\u001b[38;5;196m'
    BOLD_RED = '\u001b[31;1m'
    __reset = '\u001b[0m'
    GREEN = "\u001b[32m"
    MAGENTA= "\u001b[35m"
    CYAN= "\u001b[36m"
    BACKGROUND_RED = "\u001b[41m"
    BACKGROUND_GREEN = "\u001b[42m"

    def __init__(self, fmt):
        super().__init__()
        self.fmt = fmt
        self.__color_formats = {
            logging.DEBUG: self.GRAY + self.fmt + self.__reset,
            logging.INFO: self.BLUE + self.fmt + self.__reset,
            logging.WARNING: self.YELLOW + self.fmt + self.__reset,
            logging.ERROR: self.RED + self.fmt + self.__reset,
            logging.CRITICAL: self.BOLD_RED + self.fmt + self.__reset,
        }

    def set_level_color(self, level, color):
        """
        Color code: https://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html
        """
        self.__color_formats[level] = color + self.fmt + self.__reset

    def format(self, record):
        log_fmt = self.__color_formats.get(record.levelno)
        formatter = logging.Formatter(log_fmt)
        return formatter.format(record)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

LOG_LEVEL_CLIENT = 21
logging.CLIENT = LOG_LEVEL_CLIENT 
logging.addLevelName(logging.CLIENT, "CLIENT")

logger = logging.getLogger("color_logger")
logger.setLevel(logging.DEBUG)

#create console handler and set level to debug
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
color_formatter = CustomFormatter(FMT)
color_formatter.set_level_color(logging.CLIENT, CustomFormatter.BACKGROUND_GREEN)
handler.setFormatter(color_formatter)
logger.addHandler(handler)

# usage
logger.debug('This is a debug-level message')
logger.info('This is an info-level message')
logger.warning('This is a warning-level message')
logger.error('This is an error-level message')
logger.critical('This is a critical-level message')
logger.log(logging.CLIENT, "this is client")